// /pages/category/category.js
import { ICategoryRaw, ICategoryRender } from "@/type/index";
import { getCategory, updateCategory, addCategory } from "@/api/index";
import { showToast, showConfirmDialog } from "@/util/index";

type IFormData = Partial<Omit<ICategoryRaw, "id">>;

Page({
  data: {
    rawList: [] as ICategoryRaw[],
    renderTree: [] as ICategoryRender[],
    activeCollapse: [] as string[],
    isFormShow: false,
    formMode: "add" as "add" | "edit",
    isFormSubmitting: false,
    formData: {} as IFormData,
    editingId: null as string | null,
    parentInfo: null as ICategoryRaw | null,
    isChildForm: false,
    availableUnits: ["kg", "m", "m²", "m³", "个", "元"],
  },

  onLoad() {
    this.fetchCategoryList();
  },

  // fetchCategoryList 函数不变
  async fetchCategoryList() {
    try {
			const backendData = await getCategory();
      const parsedList = this.parseBackendDataToRawList(backendData);

      this.setData({
        rawList: parsedList,
        renderTree: this.buildRenderTree(parsedList),
      });
    } catch (error) {
      console.error("数据加载或解析失败", error);
      showToast("数据加载失败");
    }
  },

  // parseBackendDataToRawList 函数不变
  parseBackendDataToRawList(backendData: any): ICategoryRaw[] {
    const list: ICategoryRaw[] = [];
    if (!backendData || typeof backendData !== "object") {
      return [];
    }
    Object.values(backendData).forEach((parent: any) => {
      const parentCategory: ICategoryRaw = {
        id: parent._id,
        name: parent.name,
        parentId: null,
        defaultUnit: parent.defaultUnit || null,
        enable: parent.enable !== undefined ? parent.enable : true,
        remark: parent.remark || null,
      };
      list.push(parentCategory);
      if (parent.children && Array.isArray(parent.children)) {
        parent.children.forEach((child: any) => {
          const childCategory: ICategoryRaw = {
            id: child._id,
            name: child.name,
            parentId: child.parentId,
            defaultUnit: child.defaultUnit || null,
            enable:
              parent.enable !== false
                ? child.enable !== undefined
                  ? child.enable
                  : true
                : false,
            remark: child.remark || null,
          };
          list.push(childCategory);
        });
      }
    });
    return list;
  },

  // buildRenderTree 函数不变
  buildRenderTree(list: ICategoryRaw[]): ICategoryRender[] {
    const map = new Map<string, ICategoryRender>();
    const tree: ICategoryRender[] = [];
    list.forEach((item) => {
      map.set(item.id, { ...item, children: [] });
    });
    list.forEach((item) => {
      if (item.parentId && map.has(item.parentId)) {
        const parentNode = map.get(item.parentId)!;
        parentNode.children!.push(map.get(item.id)!);
      } else {
        tree.push(map.get(item.id)!);
      }
    });
    return tree;
  },

  // onCollapseChange 函数不变
  onCollapseChange(e: WechatMiniprogram.CustomEvent) {
    this.setData({ activeCollapse: e.detail.value });
  },

  /**
   * @description 【重构】处理启用/禁用切换，采用乐观更新
   */
  async onToggleEnable(e: WechatMiniprogram.TouchEvent) {
    const item = e.currentTarget.dataset.item as ICategoryRender;
    const targetEnableState = !item.enable;

    const confirm = await showConfirmDialog(
      "操作确认",
      `确定要“${targetEnableState ? "启用" : "禁用"}”分类 [${item.name}] 吗？${
        !item.parentId && !targetEnableState
          ? "\n（禁用父分类会同时禁用其所有子分类）"
          : ""
      }`
    );

    if (!confirm) return;

    // 1. 乐观更新：立即修改前端数据并刷新UI
    const originalRawList = JSON.parse(JSON.stringify(this.data.rawList)); // 深拷贝用于回滚
    const newRawList = this.data.rawList.map((raw) => {
      // 找到点击的项
      if (raw.id === item.id) {
        return { ...raw, enable: targetEnableState };
      }
      // 如果是禁用父分类，则其子分类也一并禁用
      if (!item.parentId && !targetEnableState && raw.parentId === item.id) {
        return { ...raw, enable: false };
      }
      return raw;
    });

    this.setData({
      rawList: newRawList,
      renderTree: this.buildRenderTree(newRawList),
    });
    showToast("操作成功", "success");

    // 2. 异步请求后端
    try {
      await updateCategory({
        category: item.id,
        enable: targetEnableState,
      });
      // 后端请求成功，什么都不用做，因为UI已经更新了
      console.log("后端同步成功:", item.id);
    } catch (error) {
      // 3. 如果后端请求失败，回滚数据并提示用户
      console.error("后端同步失败，正在回滚UI:", error);
      showToast("操作失败，请检查网络后重试");
      this.setData({
        rawList: originalRawList,
        renderTree: this.buildRenderTree(originalRawList),
      });
    }
  },

  // onAddCategory, onEditCategory, onCloseForm 等事件处理函数保持不变
  onAddCategory(e: WechatMiniprogram.TouchEvent) {
    const parent = e.currentTarget.dataset.parent as ICategoryRaw | undefined;
    this.setData({
      isFormShow: true,
      formMode: "add",
      editingId: null,
      formData: {
        name: "",
        parentId: parent ? parent.id : null,
        defaultUnit: null,
        enable: true,
        remark: "",
      },
      parentInfo: parent || null,
      isChildForm: !!parent,
    });
  },

  onEditCategory(e: WechatMiniprogram.TouchEvent) {
    const item = e.currentTarget.dataset.item as ICategoryRender;
    let parentInfo: ICategoryRaw | null = null;
    if (item.parentId) {
      parentInfo =
        this.data.rawList.find((p) => p.id === item.parentId) || null;
    }
    this.setData({
      isFormShow: true,
      formMode: "edit",
      editingId: item.id,
      formData: {
        name: item.name,
        parentId: item.parentId,
        defaultUnit: item.defaultUnit,
        enable: item.enable,
        remark: item.remark,
      },
      parentInfo: parentInfo,
      isChildForm: !!item.parentId,
    });
  },

  onCloseForm() {
    this.setData({ isFormShow: false });
  },

  onFormInputChange(e: WechatMiniprogram.Input) {
    const { field } = e.currentTarget.dataset;
    this.setData({ [`formData.${field}`]: e.detail.value });
  },

  onUnitChange(e: WechatMiniprogram.CustomEvent) {
    const selectedIndex = Number(e.detail.value);
    this.setData({
      "formData.defaultUnit": this.data.availableUnits[selectedIndex],
    });
  },

  /**
   * @description 【重构】提交表单，采用乐观更新
   */
  async onConfirmForm() {
    const { formData, formMode, editingId, isChildForm } = this.data;
    if (!formData.name?.trim()) {
      return showToast("分类名称不能为空");
    }
    if (isChildForm && !formData.defaultUnit) {
      return showToast("子分类必须选择单位");
    }

    this.setData({ isFormSubmitting: true });

    // 准备要提交到后端的数据（过滤掉null值）
    const backendPayload = Object.fromEntries(
      Object.entries(formData).filter(
        ([, value]) => value !== null && value !== ""
      )
    );

    // 1. 乐观更新：立即修改前端数据
    const originalRawList = JSON.parse(JSON.stringify(this.data.rawList)); // 深拷贝用于回滚
    let newRawList = [...originalRawList];
    let newOrUpdatedItem: ICategoryRaw | null = null;
    let tempId = ""; // 用于暂存新增项的临时ID

    if (formMode === "add") {
      tempId = `temp_${Date.now()}`; // 使用时间戳生成临时ID
      newOrUpdatedItem = {
        ...formData,
        id: tempId,
      } as ICategoryRaw;
      newRawList.push(newOrUpdatedItem);
    } else if (editingId) {
      const index = newRawList.findIndex((i) => i.id === editingId);
      if (index > -1) {
        newOrUpdatedItem = { ...newRawList[index], ...formData };
        newRawList[index] = newOrUpdatedItem;
      }
    }

    // 更新UI
    this.setData({
      rawList: newRawList,
      renderTree: this.buildRenderTree(newRawList),
      isFormShow: false,
    });
    showToast("提交成功", "success");

    // 2. 异步请求后端
    try {
      if (formMode === "add") {
        const result = await addCategory(backendPayload);
        // 新增成功后，用后端返回的真实ID替换掉我们的临时ID
        const realId = result._id; // 假设后端返回的数据包含真实_id
        const finalRawList = this.data.rawList.map((item) =>
          item.id === tempId ? { ...item, id: realId } : item
        );
        this.setData({
          rawList: finalRawList,
          renderTree: this.buildRenderTree(finalRawList),
        });
        console.log("后端新增成功，ID已更新:", tempId, "->", realId);
      } else if (editingId) {
        await updateCategory({
          category: editingId,
          ...backendPayload,
        });
        console.log("后端更新成功:", editingId);
      }
    } catch (error) {
      this.setData({
        rawList: originalRawList,
        renderTree: this.buildRenderTree(originalRawList),
      });
    } finally {
      this.setData({ isFormSubmitting: false });
    }
  },
});
